#include "Poller.h"
#include "Channel.h"
#include "Logger.h"
#include <unistd.h>
#include <cstring> // strerror
#include <cerrno>  // errno
#include <cassert>

namespace GiSo {

// 静态常量定义
const int Poller::s_PollTimeMs;

Poller::Poller() {
    // 创建 epoll 实例
    m_Epfd = epoll_create1(EPOLL_CLOEXEC);
    if (m_Epfd < 0) {
        GS_CRITICAL("Poller::Poller - epoll_create1 failed: {}", strerror(errno));
        abort(); // 如果创建失败，直接终止程序
    }
    // 初始化事件列表，默认容量为 16
    m_Events.resize(16);
}

Poller::~Poller() {
    // 关闭 epoll 文件描述符
    ::close(m_Epfd);
}

int Poller::Poll(int timeoutMs, ChannelList& activeChannels) {
    activeChannels.clear(); // 清空活跃事件列表
    // 调用 epoll_wait 监听事件
    int numEvents = ::epoll_wait(m_Epfd, &m_Events[0], static_cast<int>(m_Events.size()), timeoutMs);
    if (numEvents > 0) {
        // 处理活跃事件
        for (int i = 0; i < numEvents; ++i) {
            Channel* channel = static_cast<Channel*>(m_Events[i].data.ptr);
            assert(channel != nullptr);
            channel->SetRevents(m_Events[i].events);
            activeChannels.push_back(channel);
        }

        // 如果活跃事件数等于当前事件数组大小，扩容以避免下次溢出
        if (static_cast<size_t>(numEvents) == m_Events.size()) {
            m_Events.resize(m_Events.size() * 2);
            GS_DEBUG("Poller::Poll - Resized event list to {}", m_Events.size());
        }
    } else if (numEvents == 0) {
        // 超时，无事件发生
        GS_TRACE("Poller::Poll - Timeout occurred");
    } else {
        // 发生错误
        if (errno != EINTR) { // 忽略被信号中断的情况
            GS_ERROR("Poller::Poll - epoll_wait error: {}", strerror(errno));
        }
    }

    return numEvents;
}

void Poller::UpdateChannel(Channel* channel) {
    assert(channel != nullptr);

    struct epoll_event event;
    memset(&event, 0, sizeof(event)); // 清空结构体

    // 设置文件描述符和事件类型
    event.events = channel->GetEvents();
    event.data.ptr = channel; // 将 Channel 指针存储在 data.ptr 中

    int fd = channel->GetFd();
    if (channel->IsNoneEvent()) {
        // 如果没有关注任何事件，则移除监听
        RemoveChannel(channel);
    } else {
        if (channel->IsEventHandling()) {
            // 修改已存在的监听事件
            if (::epoll_ctl(m_Epfd, EPOLL_CTL_MOD, fd, &event) < 0) {
                GS_ERROR("Poller::UpdateChannel - epoll_ctl MOD error: {}", strerror(errno));
            } else {
                GS_DEBUG("Poller::UpdateChannel - Modified channel fd={}", fd);
            }
        } else {
            // 添加新的监听事件
            if (::epoll_ctl(m_Epfd, EPOLL_CTL_ADD, fd, &event) < 0) {
                GS_ERROR("Poller::UpdateChannel - epoll_ctl ADD error: {}", strerror(errno));
            } else {
                GS_DEBUG("Poller::UpdateChannel - Added channel fd={}", fd);
            }
            channel->SetEventHandling(true); // 标记为正在处理事件
        }
    }
}

void Poller::RemoveChannel(Channel* channel) {
    assert(channel != nullptr);

    int fd = channel->GetFd();
    if (::epoll_ctl(m_Epfd, EPOLL_CTL_DEL, fd, nullptr) < 0) {
        GS_ERROR("Poller::RemoveChannel - epoll_ctl DEL error: {}", strerror(errno));
    } else {
        GS_DEBUG("Poller::RemoveChannel - Removed channel fd={}", fd);
    }

    channel->SetEventHandling(false); // 标记为不再处理事件
}

} // namespace GiSo